<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是C语言基础——函数相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV01-07-C语言-函数">
<meta property="og:url" content="https://sumumm.github.io/post/203e48a8.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是C语言基础——函数相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403105523318.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403111122825.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403150919614.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220404065110961.png">
<meta property="article:published_time" content="2022-01-16T06:25:07.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:56.984Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV01-C语言基础">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403105523318.png">


<link rel="canonical" href="https://sumumm.github.io/post/203e48a8.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/203e48a8.html","path":"post/203e48a8.html","title":"LV01-07-C语言-函数"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV01-07-C语言-函数 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#1-%E4%BB%80%E4%B9%88%E6%98%AF%E5%87%BD%E6%95%B0%EF%BC%9F"><span class="nav-text">1.什么是函数？</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#2-%E4%B8%BB%E5%87%BD%E6%95%B0-main"><span class="nav-text">2.主函数 main </span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#2-1-main-%E5%87%BD%E6%95%B0%E7%9A%84%E5%BD%A2%E5%BC%8F"><span class="nav-text">2.1 main 函数的形式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-2-main-%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0"><span class="nav-text">2.2 main 函数的参数</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#3-%E8%87%AA%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0"><span class="nav-text">3.自定义函数</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#3-1%E5%87%BD%E6%95%B0%E5%AE%9A%E4%B9%89"><span class="nav-text">3.1函数定义</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-2%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E"><span class="nav-text">3.2函数声明</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-3%E5%87%BD%E6%95%B0%E8%B0%83%E7%94%A8"><span class="nav-text">3.3函数调用</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-4%E5%87%BD%E6%95%B0%E5%9C%B0%E5%9D%80"><span class="nav-text">3.4函数地址</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-5%E5%BD%A2%E5%8F%82%E4%B8%8E%E5%AE%9E%E5%8F%82"><span class="nav-text">3.5形参与实参</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-6%E5%8F%98%E9%87%8F%E4%BD%9C%E7%94%A8%E5%9F%9F"><span class="nav-text">3.6变量作用域</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-6-1%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E4%B8%8E%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F"><span class="nav-text">3.6.1全局变量与局部变量</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-6-2-static-%E5%85%B3%E9%94%AE%E5%AD%97"><span class="nav-text">3.6.2 static 关键字</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-7%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92"><span class="nav-text">3.7参数传递</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-7-1%E5%80%BC%E4%BC%A0%E9%80%92"><span class="nav-text">3.7.1值传递</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-7-2%E5%9C%B0%E5%9D%80%E4%BC%A0%E9%80%92"><span class="nav-text">3.7.2地址传递</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-7-3%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%E4%BC%A0%E5%8F%82"><span class="nav-text">3.7.3全局变量传参</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#4-%E5%87%BD%E6%95%B0%E4%B8%8E%E6%95%B0%E7%BB%84"><span class="nav-text">4.函数与数组</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#4-1%E5%BD%A2%E5%8F%82%E4%B8%BA%E6%95%B0%E7%BB%84"><span class="nav-text">4.1形参为数组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-2%E5%BD%A2%E5%8F%82%E4%B8%BA%E6%8C%87%E9%92%88"><span class="nav-text">4.2形参为指针</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-3%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E4%BC%A0%E5%8F%82"><span class="nav-text">4.3二维数组传参</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#5-%E6%8C%87%E9%92%88%E5%87%BD%E6%95%B0"><span class="nav-text">5.指针函数</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#5-1%E6%8C%87%E9%92%88%E5%87%BD%E6%95%B0%E7%9A%84%E5%AE%9A%E4%B9%89"><span class="nav-text">5.1指针函数的定义</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-2%E6%8C%87%E9%92%88%E5%87%BD%E6%95%B0%E7%9A%84%E5%BA%94%E7%94%A8"><span class="nav-text">5.2指针函数的应用</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-3%E6%8C%87%E9%92%88%E5%87%BD%E6%95%B0%E4%B8%8E%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88"><span class="nav-text">5.3指针函数与函数指针</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-4%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88%E4%BD%9C%E4%B8%BA%E8%BF%94%E5%9B%9E%E5%80%BC%EF%BC%9F"><span class="nav-text">5.4函数指针作为返回值？</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#6-%E9%80%92%E5%BD%92%E5%87%BD%E6%95%B0"><span class="nav-text">6.递归函数</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#6-1%E5%B8%B8%E8%A7%81%E7%9A%84%E4%B8%A4%E4%B8%AA%E9%97%AE%E9%A2%98"><span class="nav-text">6.1常见的两个问题</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#6-1-1%E9%98%B6%E4%B9%98%E9%97%AE%E9%A2%98"><span class="nav-text">6.1.1阶乘问题</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-1-2%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97"><span class="nav-text">6.1.2斐波那契数列</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-2%E9%80%92%E5%BD%92%E7%9A%84%E6%9D%A1%E4%BB%B6"><span class="nav-text">6.2递归的条件</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-3%E9%80%92%E5%BD%92%E5%87%BD%E6%95%B0%E7%BC%BA%E7%82%B9"><span class="nav-text">6.3递归函数缺点</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#6-3-1%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8"><span class="nav-text">6.3.1内存占用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-3-2%E6%97%B6%E9%97%B4%E6%88%90%E6%9C%AC"><span class="nav-text">6.3.2时间成本</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-4%E7%94%A8%E8%BF%AD%E4%BB%A3%E4%BB%A3%E6%9B%BF%EF%BC%9F"><span class="nav-text">6.4用迭代代替？</span></a></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/203e48a8.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV01-07-C语言-函数 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV01-07-C语言-函数
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-01-16 14:25:07" itemprop="dateCreated datePublished" datetime="2022-01-16T14:25:07+08:00">2022-01-16</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/" itemprop="url" rel="index"><span itemprop="name">01HQ课程体系</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/" itemprop="url" rel="index"><span itemprop="name">LV01-C语言基础</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>13k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>48 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是C语言基础——函数相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">SecureCRT</td>        <td align="left">Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日</td>      </tr>    <tr>        <td align="center">开发板</td>        <td align="left">正点原子 i.MX6ULL Linux阿尔法开发板</td>      </tr>    <tr>        <td align="center">uboot</td>        <td align="left">NXP官方提供的uboot，NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)</td>      </tr>    <tr>        <td align="center">linux内核</td>        <td align="left">linux-4.15(NXP官方提供)</td>      </tr>    <tr>        <td align="center">STM32开发板</td>        <td align="left">正点原子战舰V3(STM32F103ZET6)</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <table>    <tr><td align="center">参考方向  </td><td align="center">参考原文</td></tr>    <tr><td align="left">---</td><td align="left"><a href="" target="_blank">--- <i class="fa fa-external-link-alt"></i> </a></td></tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center">---</td>        <td align="left">--- <a href="" target="_blank">  <i class="fa fa-external-link-alt"></i></a></td>      </tr></table>
              </div>
            </details>

<h1 id="1-什么是函数？"><a href="#1-什么是函数？" class="headerlink" title="1.什么是函数？"></a><font size=3>1.什么是函数？</font></h1><p>函数是一个完成特定功能的代码模块，其程序代码独立，通常要求有返回值，也可以是空值。</p>
<p>函数的本质其实就是一段可以重复使用的代码，这段代码是提前编写好了的，我们使用的时候直接调取就可以。函数的实现人员将函数设置为一个“黑盒子”，隐藏实现细节，并对外部提供尽可能简单的接口，因此对于函数调用方来说，只需要关心如何提供参数，根据函数的功能可以得到什么样的结果，而函内部是如何工作的，这并不重要。</p>
<p>我们平时见到的函数，分为库函数和自定义函数。</p>
<p> C 语言自带的函数称为库函数（ Library Function ）。库（ Library ）是编程中的一个基本概念， C 语言自带的库称为标准库（ Standard Library ，例如我们常用的 stdio.h ），其他公司或个人开发的库称为第三方库（ Third-Party Library ）。</p>
<p>自定义函数就是我们自己编写的，方便自己使用的函数。</p>
<p>【注意】 C 语言中的函数在数目上没有上限，但是在 C 语言程序中，有且仅有一个名为 main 的函数。</p>
<h1 id="2-主函数-main"><a href="#2-主函数-main" class="headerlink" title="2.主函数 main "></a><font size=3>2.主函数 main </font></h1><p>我们接触到的第一个函数，其实就是 main ，这个函数被称为主函数，程序的执行总是从 main 开始，是所有程序运行的入口。</p>
<h2 id="2-1-main-函数的形式"><a href="#2-1-main-函数的形式" class="headerlink" title="2.1 main 函数的形式"></a><font size=3>2.1 main 函数的形式</font></h2><p>最新的  C99  标准中， main 函数有两种形式，一种带参数，一种不带参数。</p>
<div class="tabs" id="tabname1"><ul class="nav-tabs"><li class="tab active"><a href="#tabname1-1">无参数</a></li><li class="tab"><a href="#tabname1-2">带参数</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname1-1"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 无参数形式 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">void</span>)</span>  </span><br><span class="line">&#123;</span><br><span class="line">    语句块;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname1-2"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 带参数形式 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">    语句块;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div></div></div>

<p>其实我们也有可能会看到这种的 void main() ，但是似乎它并没有在哪种标准中被提及。有些编译器认为这样是正确的，有一些可能会认为这是错误的，所以为了程序可移植性，最好还是使用标准中的形式比较好。</p>
<h2 id="2-2-main-函数的参数"><a href="#2-2-main-函数的参数" class="headerlink" title="2.2 main 函数的参数"></a><font size=3>2.2 main 函数的参数</font></h2><p>上边我们看到，有一种带参数的主函数形式，那么这两个参数是什么呢？</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 带参数形式 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">    语句块;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<table>
    <tr>
        <td align="center" width=100px>argc</td>
        <td align="left">整型变量，表示了命令行中参数的个数(注意：文件名本身也算一个参数)</td>
    </tr>
    <tr>
        <td align="center" width=100px>argv</td>
        <td align="left">字符串型变量，它是一个指向字符串的指针数组。命令行中的每个字符串都会被存储到内存中，并且分配一个指针指向它。按照惯例，这个指针数组被称为argv（argument value），系统会使用空格把各个字符串格开。一般情况下，argv[0]是程序本身的名称，后边依次是传入的参数。</td>
    </tr>
</table>


<p> main 函数不能被其它函数调用， 因此不可能在程序内部取得实际值。那么，在何处把参数值赋予 main 函数呢? </p>
<p>实际上， main 函数的参数值是从操作系统命令行上获得的。当我们要运行一个可执行文件时，在命令行键入文件名，再输入实际参数即可把这些实参传送到 main 的参数中去。例如，在 linux 的 Shell 终端下可以这样：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./file_name arg1 arg2 ...</span><br></pre></td></tr></table></figure>

<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;argc = %d\n&quot;</span>, argc);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; argc; i++)</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;argv[%d] = %s\n&quot;</span>, i, argv[i]);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在命令行执行：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out a 1 3 &quot;Hello World !&quot; # 执行可执行文件</span><br></pre></td></tr></table></figure><p>会看到终端中有如下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">argc = 5</span><br><span class="line">argv[0] = ./a.out</span><br><span class="line">argv[1] = a</span><br><span class="line">argv[2] = 1</span><br><span class="line">argv[3] = 3</span><br><span class="line">argv[4] = Hello World !</span><br></pre></td></tr></table></figure><p>【注意】</p><p>（1）各个参数之间是通过空格隔开，我们要是想输入带空格的参数，可以使用 “ “ 包裹。</p><p>（2）在命令行的输入都将作为<strong>字符串</strong>形式存储于内存中。所以，即便参数是数字，也会被当做字符串，确实需要使用数字，还需注意做一下转换。</p>
              </div>
            </details>

<h1 id="3-自定义函数"><a href="#3-自定义函数" class="headerlink" title="3.自定义函数"></a><font size=3>3.自定义函数</font></h1><h2 id="3-1函数定义"><a href="#3-1函数定义" class="headerlink" title="3.1函数定义"></a><font size=3>3.1函数定义</font></h2><p>函数定义的一般形式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;数据类型&gt; &lt;函数名称&gt;( &lt;形式参数&gt; ) </span><br><span class="line">&#123;</span><br><span class="line">	语句块;</span><br><span class="line">	<span class="keyword">return</span> [(&lt;表达式&gt;)];</span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure>

<table>
    <tr>
        <td align="center" width=100px>数据类型</td>
        <td align="left">整个函数的返回值类型，可以是C语言中的任意数据类型，例如 int、float、char 等。可以包括存储类型说明符、数据类型说明符以及时间域说明符。如果没有返回值应该写为 void 型。</td>
    </tr>
    <tr>
        <td align="center" width=100px>函数名称</td>
        <td align="left">函数名称是一个标识符，需要符合标识符的命名规则。</td>
    </tr>
    <tr>
        <td align="center" width=100px>形式参数</td>
        <td align="left">形式参数列表，简称形参。形参可以是任意类型的变量，各参数之间用逗号(",")分隔开。在进行函数调用的时候将会赋予这些形式参数实际的值。例如，<br>dataType functionName( dataType1 param1, dataType2 param2 , ... )</td>
    </tr>
    <tr>
        <td align="center" width=100px>return</td>
        <td align="left">函数的返回值，后边表达式的值要求必须和函数名前边的数据类型保持一致。如果前边数据类型为void，那么可以写为 return;  或者全部省略，表示没有返回值</td>
    </tr>
    <tr>
        <td align="center" width=100px>&#123 &#125</td>
        <td align="left">花括号 &#123 &#125 中的内容为函数体，函数体内有若干条语句以实现特定的功能。</td>
    </tr>
</table>


<p>【注意】</p>
<p>（1）在函数体中，表达式里边使用的所有变量必须事先已有说明，否则不可以使用呢。</p>
<p>（2）形参可以缺省说明的变量名称，但类型不能缺省。例如，</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">double</span> <span class="title function_">Power</span><span class="params">(<span class="type">double</span> x, <span class="type">int</span> n)</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">/* 省略 */</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">/* 也可以写为下边的形式 */</span></span><br><span class="line"><span class="type">double</span> <span class="title function_">Power</span><span class="params">(<span class="type">double</span>, <span class="type">int</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">/* 省略 */</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>（3）函数不可以嵌套定义，就是说，不能在一个函数中定义另外一个函数，必须在所有函数之外定义另外一个函数。 main()  也是一个函数定义，也不能在  main()  函数内部定义新函数。例如，</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 下边的做法是错误的 */</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">func1</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Hello&quot;</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="type">void</span> <span class="title function_">func2</span><span class="params">()</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;World!&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>（4） return  语句是提前结束函数的唯一办法。</p>
<p>（5）<strong>可以在不同的函数中使用相同的变量名</strong>，它们表示不同的数据，分配不同的内存，互不干扰，也不会发生混淆。</p>
<p>（6）函数<strong>返回值若为整型，那么在函数定义时可以省略数据类型</strong>。但是这样做的话，很有可能会报警告，所以一般还是写上更加规范点。</p>
<h2 id="3-2函数声明"><a href="#3-2函数声明" class="headerlink" title="3.2函数声明"></a><font size=3>3.2函数声明</font></h2><p>函数定义是对函数功能的确立，包括函数名、函数返回值类型、形参列表、函数体，是一个完整、独立的函数。</p>
<p>函数声明是为了把函数名、返回值类型以及形参类型、个数和顺序通知编译系统，以便在调用该函数时，编译系统进行对照检查，包括函数名是否正确、传递参数的类型、个数是否与形参一致。如若出现不对应的情况，编译会有语法错误。</p>
<p>在 C 语言中，函数声明称为函数原型（ function prototype ）。用函数原型是 ANSIC 的一个重要特点。它的作用<strong>主要是利用它在程序的编译阶段对调用函数的合法性进行全面检查</strong>。函数原型的一般形式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;数据类型&gt; &lt;函数名称&gt;( &lt;形式参数&gt; );</span><br></pre></td></tr></table></figure>

<p>例如，</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">double</span> <span class="title function_">Power</span><span class="params">(<span class="type">double</span> x, <span class="type">int</span> n)</span>;</span><br><span class="line"><span class="comment">/* 也可以省略参数名 */</span></span><br><span class="line"><span class="type">double</span> <span class="title function_">Power</span><span class="params">(<span class="type">double</span>, <span class="type">int</span>)</span>;</span><br></pre></td></tr></table></figure>

<p>推荐一个网站，它提供了所有 C 语言标准函数的原型，并给出了详细的介绍和使用示例：</p>
<table>
    <tr>
        <td align="center" width=200>C library</td>
        <td align="left"><a href="http://www.cplusplus.com/reference/clibrary/" target="_blank">http://www.cplusplus.com/reference/clibrary/  <i class="fa fa-external-link-alt"></i> </a></td>  
    </tr>
</table>


<p>【注意】</p>
<p>（1）如果函数调用前，没有对函数作声明，且同一源文件的前面出现了该函数的定义，那么编译器就会记住它的参数数量和类型以及函数的返回值类型，即把它作为函数的声明，并将函数返回值的类型默认为 int 型。<br>（2）如果在同一源文件的前面没有该函数的定义，则需要提供该函数的函数原型。用户自定义的函数原型通常可以一起写在头文件中，通过头文件引用的方式来声明。<br>（3）编译器实际上并不检查参数名，参数名可以任意改变。所以上边的参数名可以省略。</p>
<p>（4）如果函数的声明中带有 static 关键字，那么就表示告诉编译器这个函数只能在当前文件中被调用；如果是函数声明中带有 extern 关键字，表示告诉编译器这个函数是在别的源文件中被定义的。</p>
<h2 id="3-3函数调用"><a href="#3-3函数调用" class="headerlink" title="3.3函数调用"></a><font size=3>3.3函数调用</font></h2><p>我们定义了函数，接下来就是使用了啊，一般使用形式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;函数名称&gt;( &lt;实际参数&gt; );</span><br></pre></td></tr></table></figure>

<table>
    <tr>
        <td align="center" width=100px>函数名称</td>
        <td align="left">就是定义函数的时候的函数名。</td>
    </tr>
    <tr>
        <td align="center" width=100px>实际参数</td>
        <td align="left">可以简称为实参，在使用函数时，调用函数传递给被调用函数的数据。需要确切的数据。如果有形参的话，实参与形参的个数应该相等，类型应该一致。</td>
    </tr>
</table>




<p>【注意】</p>
<p>（1）如果函数在定义的时候，没有形参，那么调用的时候也不需要传入实际参数，调用形式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;函数名称&gt;();</span><br></pre></td></tr></table></figure>

<p>（2）函数调用可以作为一个运算量出现在表达式中，也可以单独形成一个语句。对于无返回值的函数来讲，只能形成一个函数调用语句。</p>
<p>（3）函数调用支持嵌套调用。</p>
<p>如果一个函数  fun1()  在定义或调用过程中出现了对另外一个函数  fun2() 的调用，那么我们就称  fun1()  为<strong>主调函数或主函数</strong>，称  fun2()  为<strong>被调函数</strong>。</p>
<p>当主调函数遇到被调函数时，主调函数会暂停， CPU  转而执行被调函数的代码；被调函数执行完毕后再返回主调函数，主调函数根据刚才的状态继续往下执行。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">fun2</span><span class="params">(<span class="type">int</span>, <span class="type">int</span>)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> x = <span class="number">3</span>;</span><br><span class="line">	<span class="type">int</span> y = <span class="number">5</span>;</span><br><span class="line">	<span class="type">int</span> z = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">	fun1();</span><br><span class="line"></span><br><span class="line">	z = fun2(x, y);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;z = %d\n&quot;</span>, z);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is fun1!\n&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun2</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> c = <span class="number">0</span>;</span><br><span class="line">	c = a + b;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is fun2! c = %d\n&quot;</span>, c);</span><br><span class="line">	<span class="keyword">return</span> c;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">This is fun1!</span><br><span class="line">This is fun2! c = 8</span><br><span class="line">z = 8</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="3-4函数地址"><a href="#3-4函数地址" class="headerlink" title="3.4函数地址"></a><font size=3>3.4函数地址</font></h2><p>函数是一块代码，那自然要在内存中存储，那它的地址怎么获取呢？</p>
<p>函数的名称就代表了函数的地址，我们可以通过函数名打印函数存放的地址空间首地址。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	fun1();</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;fun1 = %p\n&quot;</span>, fun1);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;This is fun1!\n&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">This is fun1!</span><br><span class="line">fun1 = 0x55c7dd5076c2</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="3-5形参与实参"><a href="#3-5形参与实参" class="headerlink" title="3.5形参与实参"></a><font size=3>3.5形参与实参</font></h2><table>
    <tr>
        <td align="center" width=100px>形参</td>
        <td align="left">在函数定义中出现的参数可以看做是一个占位符，它没有数据，只能等到函数被调用时接收传递进来的数据，所以称为形式参数，简称形参。</td>
    </tr>
    <tr>
        <td align="center" width=100px>实参</td>
        <td align="left">函数被调用时给出的参数是实实在在的数据，会被函数内部的代码使用，所以称为实际参数，简称实参。</td>
    </tr>
</table>


<p>两者的功能是<strong>传递数据</strong>，发生函数调用时，实参的值会传递给形参。</p>
<ul>
<li>两者的区别与联系</li>
</ul>
<p>（1）形参变量只有在函数被调用时才会分配内存，函数调用结束后，立刻释放所分配的内存空间，所以<strong>形参只有在函数内部有效</strong>，不能在函数外部使用。调用结束回到主调函数（调用该函数的函数）后则不能使用形参中的变量。</p>
<p>（2）实参可以是<strong>常量、变量、表达式、函数</strong>等，无论实参是何种类型的数据，在进行函数调用时，它们都<strong>必须有确定的值</strong>，以便把这些值传送给形参，所以应该提前用赋值、输入等办法使实参获得确定的值。</p>
<p>（3）实参和形参<strong>在数量上、类型上、顺序上必须严格一致</strong>，否则会发生类型不匹配的错误。当然，如果能够进行自动类型转换，或者进行了强制类型转换，那么实参类型也可以不同于形参类型。</p>
<p>（4）函数调用中发生的<strong>数据传递是单向的</strong>，只能把实参的值传递给形参，而不能把形参的值反向地传递给实参。一旦完成数据的传递，实参和形参就再也没有任何关系了。所以，在函数调用过程中，形参的值发生改变并不会影响实参。</p>
<p>（5） 形参和实参<strong>可以同名</strong>，但它们之间是<strong>相互独立的，互不影响</strong>，因为实参在函数外部有效，而形参在函数内部有效。</p>
<h2 id="3-6变量作用域"><a href="#3-6变量作用域" class="headerlink" title="3.6变量作用域"></a><font size=3>3.6变量作用域</font></h2><p>前边的时候就提到了作用域的概念，但是由于没有学习函数，无法进行验证，接下来就来更加深入了解一下变量的作用域问题。</p>
<h3 id="3-6-1全局变量与局部变量"><a href="#3-6-1全局变量与局部变量" class="headerlink" title="3.6.1全局变量与局部变量"></a><font size=3>3.6.1全局变量与局部变量</font></h3><ul>
<li>局部变量</li>
</ul>
<p>定义在函数内部的变量称为<strong>局部变量</strong>（ Local Variable ），它的<strong>作用域仅限于函数内部</strong>， 离开该函数后就是无效的，再使用就会报错。</p>
<details class="folding-tag" blue><summary> 点击查看关于 main 函数的说明 </summary>
              <div class='content'>
              <p>在  main  函数中定义的变量也是局部变量，只能在  main  函数中使用。 main  函数中也不能使用其它函数中定义的变量。 main  函数也是一个函数，具有与其他函数平等的地位。</p>
              </div>
            </details>

<p>形参变量、在函数体内定义的变量都是局部变量。实参给形参传值的过程其实就是给局部变量赋值的过程。在语句块中也可定义变量，它的作用域只限于当前语句块，也相当于局部变量。例如在 while 循环， for 循环中定义的变量。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> x = <span class="number">3</span>, y = <span class="number">2</span>;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>, sum = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">	sum = fun1(x, y);</span><br><span class="line">	<span class="comment">/* 此句调用fun1函数中的局部变量，将报错 */</span></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n b = %d, &amp;b = %p&quot;</span>, a, &amp;a, b, &amp;b);</span><br><span class="line"></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;sum = %d\n&quot;</span>, sum);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">2</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="type">int</span> b = <span class="number">8</span>;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;b = %d\n&quot;</span>, b);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n----- start fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="comment">/* 此句调用main函数中的局部变量，将报错 */</span></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n y = %d, &amp;y = %p&quot;</span>, x, &amp;x, y, &amp;y);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n&quot;</span>, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;b = %d, &amp;b = %p\n&quot;</span>, b, &amp;b);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span> (a + b);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>若保存两条会报错的语句，执行完编译命令后，会有如下报错信息：</p><details class="folding-tag" blue><summary> 点击查看报错信息 </summary>              <div class='content'>              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">test.c: In function ‘main’:</span><br><span class="line">test.c:<span class="number">12</span>:<span class="number">46</span>: error: ‘a’ undeclared (first use in this function)</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n b = %d, &amp;b = %p&quot;</span>, a, &amp;a, b, &amp;b);</span><br><span class="line">                                              ^</span><br><span class="line">test.c:<span class="number">12</span>:<span class="number">46</span>: note: each undeclared identifier is reported only once <span class="keyword">for</span> each function it appears in</span><br><span class="line">test.c:<span class="number">12</span>:<span class="number">53</span>: error: ‘b’ undeclared (first use in this function)</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n b = %d, &amp;b = %p&quot;</span>, a, &amp;a, b, &amp;b);</span><br><span class="line">                                                     ^</span><br><span class="line">test.c: In function ‘fun1’:</span><br><span class="line">test.c:<span class="number">28</span>:<span class="number">46</span>: error: ‘x’ undeclared (first use in this function)</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n y = %d, &amp;y = %p&quot;</span>, x, &amp;x, y, &amp;y);</span><br><span class="line">                                              ^</span><br><span class="line">test.c:<span class="number">28</span>:<span class="number">53</span>: error: ‘y’ undeclared (first use in this function)</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n y = %d, &amp;y = %p&quot;</span>, x, &amp;x, y, &amp;y);</span><br></pre></td></tr></table></figure>              </div>            </details><p>若注释掉会报错的两句，重新执行上边两条接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">----- start fun1!-----</span><br><span class="line">a = 3, &amp;a = 0x7ffe61287fcc</span><br><span class="line">b = 2, &amp;b = 0x7ffe61287fc8</span><br><span class="line">-----end fun1!-----</span><br><span class="line">sum = 5</span><br><span class="line">b = 8</span><br><span class="line">b = 8</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<p>【注意】</p>
<p>（1）局部变量定义后，若未初始化，则值随机，并且直接编译可能会有警告提示。</p>
<p>（2）语句块中定义局部变量，不仅仅可以在 while 循环， for 循环中定义， C 语言也云心出现单独的 {} ，这也是一个作用域。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> n = <span class="number">22</span>; </span><br><span class="line">    <span class="comment">/* 由&#123; &#125;包围的代码块 */</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="type">int</span> n = <span class="number">40</span>;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;block n: %d\n&quot;</span>, n);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;main n: %d\n&quot;</span>, n);</span><br><span class="line">   </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">block n: 40</span><br><span class="line">main n: 22</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<ul>
<li>全局变量</li>
</ul>
<p>在所有函数外部定义的变量称为<strong>全局变量</strong>（ Global Variable ），它的作用域默认是整个程序，也就是所有的源文件，包括  .c  和  .h  文件。</p>
<p>全局变量和局部变量可以同名，但是在局部范围内全局变量会被“屏蔽”，不再起作用。也就是，<strong>变量的使用遵循就近原则</strong>，如果在当前作用域中存在同名变量，就不会向更大的作用域中去寻找变量。</p>
<p>【注意】</p>
<p>（1）全局变量定义后若未初始化，则自动赋值空值。</p>
<p>（2） C 语言规定，只能从小的作用域向大的作用域中去寻找变量。</p>
<p>（3）在一个函数内部修改全局变量的值会影响其它函数，全局变量的值在函数内部被修改后并不会自动恢复，它会一直保留该值，直到下次被修改。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> global;</span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">fun2</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;global = %d, &amp;global = %p\n&quot;</span>, global, &amp;global);</span><br><span class="line"></span><br><span class="line">	<span class="type">int</span> global = <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;global = %d, &amp;global = %p\n&quot;</span>, global, &amp;global);</span><br><span class="line"></span><br><span class="line">	fun1();</span><br><span class="line">	fun2();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n----- start fun1!-----\n&quot;</span>);</span><br><span class="line">	global = <span class="number">11</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;global = %d, &amp;global = %p\n&quot;</span>, global, &amp;global);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun2</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n----- start fun2!-----\n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;global = %d, &amp;global = %p\n&quot;</span>, global, &amp;global);</span><br><span class="line">	<span class="type">int</span> global = <span class="number">22</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;global = %d, &amp;global = %p\n&quot;</span>, global, &amp;global);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun2!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">global = 0, &amp;global = 0x56016f5a5014</span><br><span class="line">global = 20, &amp;global = 0x7ffd04c87cb4</span><br><span class="line"></span><br><span class="line">----- start fun1!-----</span><br><span class="line">global = 11, &amp;global = 0x56016f5a5014</span><br><span class="line">-----end fun1!-----</span><br><span class="line"></span><br><span class="line">----- start fun2!-----</span><br><span class="line">global = 11, &amp;global = 0x56016f5a5014</span><br><span class="line">global = 22, &amp;global = 0x7ffd04c87c84</span><br><span class="line">-----end fun2!-----</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h3 id="3-6-2-static-关键字"><a href="#3-6-2-static-关键字" class="headerlink" title="3.6.2 static 关键字"></a><font size=3>3.6.2 static 关键字</font></h3><ul>
<li>静态局部变量</li>
</ul>
<p>前边也有提到<strong>静态局部变量</strong>，加上该关键字的局部变量拥有更长的生存周期，但是当函数结束的时候此变量存储空间虽然不会释放，原来的值也会保留，但是便无法再使用。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n----- First fun1!-----\n&quot;</span>);</span><br><span class="line">	fun1();</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n----- Second fun1!-----\n&quot;</span>);</span><br><span class="line">	fun1();</span><br><span class="line">	<span class="comment">/* 以下两句访问fun1中的静态局部变量，将会报错*/</span></span><br><span class="line">	<span class="comment">// printf(&quot;a = %d\n&quot;, a);</span></span><br><span class="line">	<span class="comment">// printf(&quot;&amp;a = %p\n&quot;, &amp;a);</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;----- start fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="type">static</span> <span class="type">int</span> a = <span class="number">11</span>;</span><br><span class="line">	<span class="type">int</span> b = <span class="number">3</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n&quot;</span>, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;b = %d, &amp;b = %p\n&quot;</span>, b, &amp;b);</span><br><span class="line"></span><br><span class="line">	a++;</span><br><span class="line">	b++;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n&quot;</span>, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;b = %d, &amp;b = %p\n&quot;</span>, b, &amp;b);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>若保存两条会报错的语句，执行完编译命令后，会有如下报错信息：</p><details class="folding-tag" blue><summary> 点击查看报错信息 </summary>              <div class='content'>              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">test.c: In function ‘main’:</span><br><span class="line">test.c:<span class="number">12</span>:<span class="number">21</span>: error: ‘a’ undeclared (first use in this function)</span><br><span class="line">  <span class="built_in">printf</span>(<span class="string">&quot;a = %d\n&quot;</span>, a);</span><br><span class="line">                     ^</span><br><span class="line">test.c:<span class="number">12</span>:<span class="number">21</span>: note: each undeclared identifier is reported only once <span class="keyword">for</span> each function it appears in</span><br></pre></td></tr></table></figure>              </div>            </details><p>若注释掉会报错的两句，重新执行上边两条接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">----- First fun1!-----</span><br><span class="line">----- start fun1!-----</span><br><span class="line">a = 11, &amp;a = 0x55d500b8f010</span><br><span class="line">b = 3, &amp;b = 0x7fff751bb6d4</span><br><span class="line">a = 12, &amp;a = 0x55d500b8f010</span><br><span class="line">b = 4, &amp;b = 0x7fff751bb6d4</span><br><span class="line">-----end fun1!-----</span><br><span class="line"></span><br><span class="line">----- Second fun1!-----</span><br><span class="line">----- start fun1!-----</span><br><span class="line">a = 12, &amp;a = 0x55d500b8f010</span><br><span class="line">b = 3, &amp;b = 0x7fff751bb6d4</span><br><span class="line">a = 13, &amp;a = 0x55d500b8f010</span><br><span class="line">b = 4, &amp;b = 0x7fff751bb6d4</span><br><span class="line">-----end fun1!-----</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<ul>
<li>静态的全局变量</li>
</ul>
<p>那在全局变量前边加上该关键字呢？这样就会把这个全局变量的作用域限制在当前文件中，这里先用一下后边会学到的多文件编程，具体的可以看下一节。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <div class="tabs" id="tabname2"><ul class="nav-tabs"><li class="tab active"><a href="#tabname2-1">main.c</a></li><li class="tab"><a href="#tabname2-2">fun1.c</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname2-1"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="keyword">extern</span> <span class="type">int</span> a;</span><br><span class="line"><span class="keyword">extern</span> <span class="type">int</span> b;</span><br><span class="line"><span class="keyword">extern</span> <span class="type">void</span> <span class="title function_">fun1</span><span class="params">(<span class="type">void</span>)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">    fun1();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;main:a = %d,\n&quot;</span>, a);</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;main:b = %d,\n&quot;</span>, b);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div><div class="tab-pane" id="tabname2-2"><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="type">int</span> a = <span class="number">10</span>;</span><br><span class="line"><span class="type">static</span> <span class="type">int</span> b = <span class="number">20</span>;</span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;fun1:a = %d, b = %d\n&quot;</span>, a, b);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></div></div></div><p>在终端执行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc *.c -Wall    # 编译程序 </span><br></pre></td></tr></table></figure><p>会在终端看到以下提示信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/tmp/ccRSRi58.o：在函数‘main’中：</span><br><span class="line">main.c:(.text+0x2f)：对‘b’未定义的引用</span><br><span class="line">collect2: error: ld returned 1 exit status</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="3-7参数传递"><a href="#3-7参数传递" class="headerlink" title="3.7参数传递"></a><font size=3>3.7参数传递</font></h2><p>主要有三种传递参数的方式，分别是值传递，地址传递和全局变量。</p>
<h3 id="3-7-1值传递"><a href="#3-7-1值传递" class="headerlink" title="3.7.1值传递"></a><font size=3>3.7.1值传递</font></h3><p>值传递，其实就是进行复制传递。调用函数将实参传递给被调用函数，被调用函数将创建同类型的形参并用实参初始化。形参是新开辟的存储空间，因此，在函数中改变形参的值，不会影响到实参。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span>, <span class="type">int</span>)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> x = <span class="number">3</span>;</span><br><span class="line">	<span class="type">int</span> y = <span class="number">6</span>;</span><br><span class="line">	<span class="type">int</span> sum = <span class="number">0</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n&quot;</span>, x, &amp;x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;y = %d, &amp;y = %p\n&quot;</span>, y, &amp;y);</span><br><span class="line"></span><br><span class="line">	fun1(x, y);</span><br><span class="line"></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n&quot;</span>, x, &amp;x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;y = %d, &amp;y = %p\n&quot;</span>, y, &amp;y);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;----- start fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n&quot;</span>, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;b = %d, &amp;b = %p\n&quot;</span>, b, &amp;b);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;----- change-----\n&quot;</span>);</span><br><span class="line">	<span class="type">int</span> temp = <span class="number">0</span>;</span><br><span class="line">	temp = a;</span><br><span class="line">	a = b;</span><br><span class="line">	b = temp;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = %d, &amp;a = %p\n&quot;</span>, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;b = %d, &amp;b = %p\n&quot;</span>, b, &amp;b);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">x = 3, &amp;x = 0x7fff151a19bc</span><br><span class="line">y = 6, &amp;y = 0x7fff151a19c0</span><br><span class="line">----- start fun1!-----</span><br><span class="line">a = 3, &amp;a = 0x7fff151a197c</span><br><span class="line">b = 6, &amp;b = 0x7fff151a1978</span><br><span class="line">----- change-----</span><br><span class="line">a = 6, &amp;a = 0x7fff151a197c</span><br><span class="line">b = 3, &amp;b = 0x7fff151a1978</span><br><span class="line">-----end fun1!-----</span><br><span class="line">x = 3, &amp;x = 0x7fff151a19bc</span><br><span class="line">y = 6, &amp;y = 0x7fff151a19c0</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<p>上述例子中实参与形参关系如下图所示：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403105523318.png" alt="image-20220403105523318" style="zoom:50%;" />

<p>可以发现，实际参数 x 和 y 的值并没有受到任何影响。</p>
<h3 id="3-7-2地址传递"><a href="#3-7-2地址传递" class="headerlink" title="3.7.2地址传递"></a><font size=3>3.7.2地址传递</font></h3><p>那我们想要在函数中修改传入参数的数据，就可以使用地址传递。</p>
<p>地址传递方式是按地址传递，实参为变量的地址，而形参为同类型的指针。被调用函数中对形参的操作，将直接改变实参的值（被调用函数对指针的目标操作，相当于对实参本身的操作）</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> *, <span class="type">int</span> *)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> x = <span class="number">3</span>;</span><br><span class="line">	<span class="type">int</span> y = <span class="number">6</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n&quot;</span>, x, &amp;x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;y = %d, &amp;y = %p\n&quot;</span>, y, &amp;y);</span><br><span class="line"></span><br><span class="line">	fun1(&amp;x, &amp;y);</span><br><span class="line"></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;x = %d, &amp;x = %p\n&quot;</span>, x, &amp;x);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;y = %d, &amp;y = %p\n&quot;</span>, y, &amp;y);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">void</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> *a, <span class="type">int</span> *b)</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;----- start fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;*a = %d, a = %p, &amp;a = %p\n&quot;</span>, *a, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;*b = %d, b = %p, &amp;b = %p\n&quot;</span>, *b, b, &amp;b);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;----- change-----\n&quot;</span>);</span><br><span class="line">	<span class="type">int</span> temp = <span class="number">0</span>;</span><br><span class="line">	temp = *a;</span><br><span class="line">	*a = *b;</span><br><span class="line">	*b = temp;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;*a = %d, a = %p, &amp;a = %p\n&quot;</span>, *a, a, &amp;a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;*b = %d, b = %p, &amp;b = %p\n&quot;</span>, *b, b, &amp;b);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">x = 3, &amp;x = 0x7fffee759b50</span><br><span class="line">y = 6, &amp;y = 0x7fffee759b54</span><br><span class="line">----- start fun1!-----</span><br><span class="line">*a = 3, a = 0x7fffee759b50, &amp;a = 0x7fffee759b18</span><br><span class="line">*b = 6, b = 0x7fffee759b54, &amp;b = 0x7fffee759b10</span><br><span class="line">----- change-----</span><br><span class="line">*a = 6, a = 0x7fffee759b50, &amp;a = 0x7fffee759b18</span><br><span class="line">*b = 3, b = 0x7fffee759b54, &amp;b = 0x7fffee759b10</span><br><span class="line">-----end fun1!-----</span><br><span class="line">x = 6, &amp;x = 0x7fffee759b50</span><br><span class="line">y = 3, &amp;y = 0x7fffee759b54</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<p>上述例子中实参与形参关系如下图所示：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403111122825.png" alt="image-20220403111122825" style="zoom:50%;" />

<p>可以发现，实际参数 x 和 y 的值也被交换了。</p>
<h3 id="3-7-3全局变量传参"><a href="#3-7-3全局变量传参" class="headerlink" title="3.7.3全局变量传参"></a><font size=3>3.7.3全局变量传参</font></h3><p>前边我们知道，全局变量一旦定义，会在程序的任何地方可见，但是，全局变量的值可能会在任何一个函数中被修改，一经修改，就会影响其他所有使用它的地方，而且使用全局变量传递参数的先后吮吸不同也可能会影响最终结果。所以<strong>一般不建议使用这种传参方式</strong>。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> n = <span class="number">3</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> sum = <span class="number">0</span>;</span><br><span class="line">	sum = fun1();</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;sum = %d\n&quot;</span>, sum);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">()</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;----- start fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="type">int</span> count = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt;= n; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		count++;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;-----end fun1!-----\n&quot;</span>);</span><br><span class="line">	<span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">----- start fun1!-----</span><br><span class="line">-----end fun1!-----</span><br><span class="line">sum = 4</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h1 id="4-函数与数组"><a href="#4-函数与数组" class="headerlink" title="4.函数与数组"></a><font size=3>4.函数与数组</font></h1><p>很多时候，我们处理数据并不是单一的处理一个或者几个数据，这个时候我们就可以使用数组来传参，便于数据处理。</p>
<h2 id="4-1形参为数组"><a href="#4-1形参为数组" class="headerlink" title="4.1形参为数组"></a><font size=3>4.1形参为数组</font></h2><p>实参为数组名（也可以说是数组的指针），形参为数组名（本质是一个指针变量）。</p>
<p>这种方式传入数组时，形参并没有赋值实参所有的元素，而是复制了实参的首地址，这也就意味着我们<strong>传入的参数实际上是一个地址</strong>。这也说明了我们在函数中对数组元素进行操作，原来数组中的元素会相应发生变化。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <p>【注意】形参是数组形式时，本质是同级别的指针。例如，</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span>;</span><br><span class="line"><span class="comment">/* 里边的 int arr[] 相当于下边的写法 */</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> *arr, <span class="type">int</span> n)</span>;</span><br></pre></td></tr></table></figure><div class="tabs" id="tabname3"><ul class="nav-tabs"><li class="tab active"><a href="#tabname3-1">形式一</a></li><li class="tab"><a href="#tabname3-2">形式二</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname3-1"><ul><li>形式参数是一个未定义大小的数组</li></ul><details class="folding-tag" blue><summary> 点击查看实例 </summary>              <div class='content'>              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span>;</span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> a[<span class="number">5</span>] = &#123;<span class="number">1</span>, <span class="number">7</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">5</span>&#125;;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = &quot;</span>);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;%d\t&quot;</span>,a[i]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">    </span><br><span class="line">	selectSort(a, <span class="keyword">sizeof</span>(a)/<span class="keyword">sizeof</span>(<span class="type">int</span>));</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = &quot;</span>);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;%d\t&quot;</span>,a[i]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">    </span><br><span class="line">   <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> arr[], <span class="type">int</span> n)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> temp = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; n; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">for</span>(j = <span class="number">0</span>; j &lt; n - <span class="number">1</span>; j++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[j] &gt; arr[j+<span class="number">1</span>])</span><br><span class="line">            &#123;</span><br><span class="line">                temp=arr[j];</span><br><span class="line">                arr[j]=arr[j+<span class="number">1</span>];</span><br><span class="line">                arr[j+<span class="number">1</span>]=temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a = 1   7       3       2       5</span><br><span class="line">a = 1   2       3       5       7</span><br></pre></td></tr></table></figure>              </div>            </details></div><div class="tab-pane" id="tabname3-2"><ul><li>形式参数是一个已定义大小的数组</li></ul><details class="folding-tag" blue><summary> 点击查看实例 </summary>              <div class='content'>              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> arr[<span class="number">5</span>])</span>;</span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> a[<span class="number">5</span>] = &#123;<span class="number">1</span>, <span class="number">7</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">5</span>&#125;;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = &quot;</span>);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;%d\t&quot;</span>,a[i]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">	selectSort(a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = &quot;</span>);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;%d\t&quot;</span>,a[i]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">    </span><br><span class="line">   <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> arr[<span class="number">5</span>])</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> temp = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">for</span>(j = <span class="number">0</span>; j &lt; <span class="number">5</span> - <span class="number">1</span>; j++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[j] &gt; arr[j+<span class="number">1</span>])</span><br><span class="line">            &#123;</span><br><span class="line">                temp=arr[j];</span><br><span class="line">                arr[j]=arr[j+<span class="number">1</span>];</span><br><span class="line">                arr[j+<span class="number">1</span>]=temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a = 1   7       3       2       5</span><br><span class="line">a = 1   2       3       5       7</span><br></pre></td></tr></table></figure><p>这里为什么不通过 sizeof 计算数组大小呢，是因为它会报以下警告：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">warning: ‘sizeof’ on array function parameter ‘arr’ will return size of ‘int *’ [-Wsizeof-array-argument]</span><br></pre></td></tr></table></figure><p>函数的形参即便是一个已经定义了大小的数组，但是这个形参的数组名被认为是一个指针类型了。</p>              </div>            </details></div></div></div>
              </div>
            </details>

<h2 id="4-2形参为指针"><a href="#4-2形参为指针" class="headerlink" title="4.2形参为指针"></a><font size=3>4.2形参为指针</font></h2><p>既然传入的参数是一个地址，那么当然可以用指针来接收地址了。一般形式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">dataType <span class="title function_">functionName</span><span class="params">(dataType *arg1, <span class="type">int</span> length)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">/* 省略 */</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> *arr, <span class="type">int</span> n)</span>;</span><br><span class="line"> </span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> a[<span class="number">5</span>] = &#123;<span class="number">1</span>, <span class="number">7</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">5</span>&#125;;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = &quot;</span>);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;%d\t&quot;</span>,a[i]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line"></span><br><span class="line">	selectSort(a, <span class="number">5</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;a = &quot;</span>);</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;%d\t&quot;</span>,a[i]);</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">    </span><br><span class="line">   <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="type">void</span> <span class="title function_">selectSort</span><span class="params">(<span class="type">int</span> *arr, <span class="type">int</span> n)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> temp = <span class="number">0</span>;</span><br><span class="line">	</span><br><span class="line">    <span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">for</span>(j = <span class="number">0</span>; j &lt; <span class="number">5</span> - <span class="number">1</span>; j++)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span>(arr[j] &gt; arr[j+<span class="number">1</span>])</span><br><span class="line">            &#123;</span><br><span class="line">                temp=arr[j];</span><br><span class="line">                arr[j]=arr[j+<span class="number">1</span>];</span><br><span class="line">                arr[j+<span class="number">1</span>]=temp;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">a = 1   7       3       2       5</span><br><span class="line">a = 1   2       3       5       7</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="4-3二维数组传参"><a href="#4-3二维数组传参" class="headerlink" title="4.3二维数组传参"></a><font size=3>4.3二维数组传参</font></h2><p>二维数组也是类似的传参方式。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <div class="tabs" id="tabname4"><ul class="nav-tabs"><li class="tab active"><a href="#tabname4-1">形式一</a></li><li class="tab"><a href="#tabname4-2">形式二</a></li></ul><div class="tab-content"><div class="tab-pane active" id="tabname4-1"><ul><li>形式参数是一个未定义大小的二维数组</li></ul><p>第一维的大小可以不指定，第二维的大小<strong>必须指定</strong>。</p><details class="folding-tag" blue><summary> 点击查看实例 </summary>              <div class='content'>              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m, <span class="type">int</span> arr[][m])</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> a[<span class="number">2</span>][<span class="number">3</span>] = &#123;&#123;<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>&#125;, &#123;<span class="number">5</span>, <span class="number">7</span> ,<span class="number">6</span>&#125;&#125;;</span><br><span class="line">	<span class="type">int</span> (*p)[<span class="number">3</span>] = a;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> sum = <span class="number">0</span>, n, m;</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">2</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">for</span>(j = <span class="number">0</span>; j &lt;<span class="number">3</span>; j++)</span><br><span class="line">		&#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">&quot;a[%d][%d] = %d \t&quot;</span>, i, j, *(*(p + i) + j));</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	n = <span class="keyword">sizeof</span>(a)/<span class="keyword">sizeof</span>(a[<span class="number">0</span>]);</span><br><span class="line">	m = <span class="keyword">sizeof</span>(a[<span class="number">0</span>])/<span class="keyword">sizeof</span>(<span class="type">int</span>);</span><br><span class="line">	sum = fun1(n, m, a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;sum = %d\n&quot;</span>, sum);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m, <span class="type">int</span> arr[][m])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> sum = <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; n; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">for</span>(j = <span class="number">0</span>; j &lt; m; j++)</span><br><span class="line">		&#123;</span><br><span class="line">			sum += arr[i][j];</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a[0][0] = 1     a[0][1] = 3     a[0][2] = 2 </span><br><span class="line">a[1][0] = 5     a[1][1] = 7     a[1][2] = 6 </span><br><span class="line">sum = 24</span><br></pre></td></tr></table></figure>              </div>            </details></div><div class="tab-pane" id="tabname4-2"><ul><li>形式参数是一个行指针</li></ul><details class="folding-tag" blue><summary> 点击查看实例 </summary>              <div class='content'>              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m, <span class="type">int</span> (*arr)[m])</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">const</span> <span class="type">char</span> *argv[])</span> </span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> a[<span class="number">2</span>][<span class="number">3</span>] = &#123;&#123;<span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>&#125;, &#123;<span class="number">5</span>, <span class="number">7</span> ,<span class="number">6</span>&#125;&#125;;</span><br><span class="line">	<span class="type">int</span> (*p)[<span class="number">3</span>] = a;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> sum = <span class="number">0</span>, n, m;</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; <span class="number">2</span>; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">for</span>(j = <span class="number">0</span>; j &lt;<span class="number">3</span>; j++)</span><br><span class="line">		&#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">&quot;a[%d][%d] = %d \t&quot;</span>, i, j, *(*(p + i) + j));</span><br><span class="line">		&#125;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;\n&quot;</span>);</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	n = <span class="keyword">sizeof</span>(a)/<span class="keyword">sizeof</span>(a[<span class="number">0</span>]);</span><br><span class="line">	m = <span class="keyword">sizeof</span>(a[<span class="number">0</span>])/<span class="keyword">sizeof</span>(<span class="type">int</span>);</span><br><span class="line">	sum = fun1(n, m, a);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;sum = %d\n&quot;</span>, sum);</span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">fun1</span><span class="params">(<span class="type">int</span> n, <span class="type">int</span> m, <span class="type">int</span> (*arr)[m])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> j = <span class="number">0</span>;</span><br><span class="line">	<span class="type">int</span> sum = <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">for</span>(i = <span class="number">0</span>; i &lt; n; i++)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">for</span>(j = <span class="number">0</span>; j &lt; m; j++)</span><br><span class="line">		&#123;</span><br><span class="line">			sum += *(*(arr + i) + j);</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a[0][0] = 1     a[0][1] = 3     a[0][2] = 2 </span><br><span class="line">a[1][0] = 5     a[1][1] = 7     a[1][2] = 6 </span><br><span class="line">sum = 24</span><br></pre></td></tr></table></figure>              </div>            </details></div></div></div>
              </div>
            </details>

<h1 id="5-指针函数"><a href="#5-指针函数" class="headerlink" title="5.指针函数"></a><font size=3>5.指针函数</font></h1><p>在 C 语言中允许一个函数的返回值是一个指针（即地址），这种返回指针值的函数称为<strong>指针函数</strong>。</p>
<h2 id="5-1指针函数的定义"><a href="#5-1指针函数的定义" class="headerlink" title="5.1指针函数的定义"></a><font size=3>5.1指针函数的定义</font></h2><p>指针函数定义的一般形式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;数据类型&gt; *&lt;函数名称&gt;( &lt;形式参数&gt; ) </span><br><span class="line">&#123;</span><br><span class="line">	语句块;</span><br><span class="line">	<span class="keyword">return</span> [ address ];</span><br><span class="line">&#125; </span><br></pre></td></tr></table></figure>

<p>【注意】</p>
<p>（1）比起普通的自定义函数，在函数名称前多了一个 * 。</p>
<p>（2）<strong>返回值</strong>与一般自定义函数不同，指针函数的返回值必须是一个地址量。可以是全局变量的地址、 static 变量的地址、字符串常量的地址或者堆的地址。</p>
<p>不可以返回局部变量的地址，因为局部变量在函数运行完的时候，它所占用的内存被释放掉了，我们不能在主调函数中再访问该局部变量的地址，<strong>访问一段已经释放的内存，是一种非法操作</strong>。</p>
<p>【示例分析】</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> *<span class="title function_">pfunc</span><span class="params">(<span class="type">int</span>, <span class="type">int</span>)</span>;</span><br></pre></td></tr></table></figure>

<p>（1） * 运算符的优先级低于 () ，所以 pfunc 先与 () 结合，说明这是一个函数，也就可以写成这样</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> *( pfunc(<span class="type">int</span>, <span class="type">int</span>) );</span><br><span class="line">      ---------------</span><br></pre></td></tr></table></figure>

<p>（2） pfunc 是一个函数，括号里边是两个 int 类型的形参列表，这说明 pfunc 函数带有两个 int 类型的形参，使用的时候需要传入两个 int 类型的实参。</p>
<p>（3）再看前边的 * ，说明这个函数的返回值是一个指针变量。</p>
<p>（4） * 前边的 int 表明返回的指针变量是 int 类型的。</p>
<p>总的来说，就是定义了一个名为 pfunc 的函数，函数有两个 int 类型的形参，函数返回一个指向整型数据的指针变量。</p>
<h2 id="5-2指针函数的应用"><a href="#5-2指针函数的应用" class="headerlink" title="5.2指针函数的应用"></a><font size=3>5.2指针函数的应用</font></h2><p>函数库中有字符串拼接函数，我们是不是可以考虑使用指针函数自己实现一个呢？</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">char</span> *<span class="title function_">myStrcat</span><span class="params">(<span class="type">char</span> *dest, <span class="type">const</span> <span class="type">char</span> *src)</span>;  <span class="comment">/* 函数声明 */</span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="type">char</span> str[<span class="number">50</span>] = <span class="string">&quot;Hello world!\x23welcome&quot;</span>;</span><br><span class="line">	<span class="type">char</span> str2[] = <span class="string">&quot; here!&quot;</span>;</span><br><span class="line">	</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;str[50] = %s, str2[] = %s\n&quot;</span>, str, str2);</span><br><span class="line"></span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;myStrcat(str, str2) = %s, str2[] = %s\n&quot;</span>, myStrcat(str, str2), str2);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 字符串拼接函数 */</span></span><br><span class="line"><span class="type">char</span> *<span class="title function_">myStrcat</span><span class="params">(<span class="type">char</span> *dest, <span class="type">const</span> <span class="type">char</span> *src)</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">char</span> *restore = dest; <span class="comment">/* 指向要返回的字符串的首地址 */</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(*dest++); <span class="comment">/* 定位到 *dest 指向的字符串中的 \0 结束符处  */</span></span><br><span class="line">    dest--;         <span class="comment">/* 当 *dest = &#x27;\0&#x27;时循环结束,但是dest指向了 &#x27;\0&#x27; 后边的地址*/</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span>(*src)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// printf(&quot;*dest=%s, *src=%c----------&quot;, restore, *src);</span></span><br><span class="line">        *dest++ = *src++;</span><br><span class="line">        <span class="comment">// printf(&quot;*dest=%s, *src=%c\n&quot;, restore, *src);</span></span><br><span class="line">    &#125;</span><br><span class="line">    *dest = <span class="string">&#x27;\0&#x27;</span>;  <span class="comment">/* 结尾补充一个&#x27;\0&#x27;,可以预防字符串中间有 &#x27;\0&#x27; 的情况 */</span></span><br><span class="line">    <span class="keyword">return</span> restore;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">str[50] = Hello world!#welcome, str2[] =  here!</span><br><span class="line">myStrcat(str, str2) = Hello world!#welcome here!, str2[] =  here!</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="5-3指针函数与函数指针"><a href="#5-3指针函数与函数指针" class="headerlink" title="5.3指针函数与函数指针"></a><font size=3>5.3指针函数与函数指针</font></h2><p>首先，还是上边的例子，一个指针函数：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> *<span class="title function_">pfunc</span><span class="params">(<span class="type">int</span>, <span class="type">int</span>)</span>;</span><br></pre></td></tr></table></figure>

<p>对于这个例子，我们前边是这样分析的：</p>
<details class="folding-tag" blue><summary> 点击查看分析过程 </summary>
              <div class='content'>
              <p>（1） * 运算符的优先级低于 () ，所以 pfunc 先与 () 结合，说明这是一个函数，也就可以写成这样</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> *(pfunc(<span class="type">int</span>, <span class="type">int</span>));</span><br></pre></td></tr></table></figure><p>（2） pfunc 是一个函数，括号里边是两个 int 类型的形参列表，这说明 pfunc 函数带有两个 int 类型的形参，使用的时候需要传入两个 int 类型的实参。</p><p>（3）再看前边的 * ，说明这个函数的返回值是一个指针变量。</p><p>（4） * 前边的 int 表明返回的指针变量是 int 类型的。</p><p>总的来说，就是定义了一个名为 pfunc 的函数，函数有两个 int 类型的形参，函数返回一个指向整型数据的指针变量。</p>
              </div>
            </details>

<p>前边学了函数指针，怎么变成一个函数指针？像下边这样既可：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> (*pfunc)(<span class="type">int</span>, <span class="type">int</span>);</span><br></pre></td></tr></table></figure>

<details class="folding-tag" blue><summary> 点击查看分析过程 </summary>
              <div class='content'>
              <p>（1）这里还是先看 pfunc ，通过 () 强行与 * 相结合，这就意味着 pfunc 是一个指针变量。</p><p>（2）接着后边是 (int, int) ，这说明这个指针变量指向了一个函数，函数可以带两个 int 类型的参数。</p><p>（3）最前边的 int 表明，函数的返回值是 int 类型。</p><p>总的来说，就是定义了一个名为 pfunc 的指针变量，这个指针变量可以指向返回值为 int 类型，且带有两个 int 类型参数的函数。</p>
              </div>
            </details>

<p>【结论】根据上边的分析，两个语句，仅仅是一个 () 的区别，所代表的含义就完全不同了，由对两个语句的分析可知，<strong>函数指针</strong>本质上还<strong>是一个指针</strong>，它可以<strong>指向一个函数</strong>；而<strong>指针函数</strong>本质上<strong>是一个函数</strong>，它可以<strong>返回一个指针</strong>。</p>
<h2 id="5-4函数指针作为返回值？"><a href="#5-4函数指针作为返回值？" class="headerlink" title="5.4函数指针作为返回值？"></a><font size=3>5.4函数指针作为返回值？</font></h2><p>上边分析完函数指针和指针函数后，想到了点变态的东西，就是，函数指针既然是一个指针，而指针函数既然是一个函数，返回值为指针，那么它俩结合一下，简直不敢想象，太可怕了，但是后边还真遇到了这样的函数。既然后边会遇到，那就在这里总结一下，分析一下吗，彻底搞明白好啦。</p>
<p>自己写，目前似乎还写不出来，直接找个例子分析一下吧：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> (*func(<span class="type">int</span>))(<span class="type">int</span> *, <span class="type">int</span>);</span><br></pre></td></tr></table></figure>

<p>（1）先看名称，也就是 func ，由于 * 的优先级低于 () ，所以 func 与 () 结合，说明这是一个函数，所以也就可以写成这样了：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> (  *(func(<span class="type">int</span>)  )(<span class="type">int</span> *, <span class="type">int</span>);</span><br><span class="line">       ------------</span><br></pre></td></tr></table></figure>

<p>（2） () 里边的 int 表示函数 func 带有一个 int 类型的形参。</p>
<p>（3）接着就是 * ，这表示这个函数的返回值是一个指针变量，然后就该最后的一个括号了，也就是</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> (  *(func(<span class="type">int</span>)  )( <span class="type">int</span> *, <span class="type">int</span> );</span><br><span class="line">                      ------------</span><br></pre></td></tr></table></figure>

<p>（4）我们已经分析出来第一个 () 中是一个指针变量，那我们用 *p 暂时代替一下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> (*p)( <span class="type">int</span> *, <span class="type">int</span> );</span><br><span class="line">         ------------</span><br></pre></td></tr></table></figure>

<p>这样是不是就清楚多了呢？前边的 *p 是一个指针变量，后边的 () 表示这是一个函数，也就是说 p 指向了一个函数。</p>
<p>（5）最后的 () 里边表示这个函数有两个参数，一个是 int 类型指针，传输参数的时候需要传一个指针变量，另一个是 int 类型变量。结合 （4） 就是有一个指针 p 指向一个带有两个参数的函数。</p>
<p>（6）最前边的 int 表示 p 指向的函数的返回值为 int 类型。</p>
<p>总的来说就是，定义了一个指针函数，函数名为 func ，函数带有一个 int 类型的参数，这个函数的返回值是一个指针变量，函数返回的指针变量又是一个函数指针，它可以指向一个带有两个参数的且返回值为 int 类型的函数。这就是前边说的，定义了一个指针函数，指针函数返回一个可以指向函数指针。</p>
<p>对于我来说，简直是难以理解，甚至可以说是，几乎理解不了，那有什么办法简化嘛？当然有啦，哈哈哈。还记得 typedef 吧，我看我的笔记似乎是记在用户自定义类型那了，但是问题不大，我们接下来就看一看这个关键字是如何简化上边的，额。。。就这样吧。</p>
<p>上边我们分析到第 (4) 步的时候，我们用了一个指针 p 代替了 func(int) ，所以就成了下边的这个样子：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> (*p)(<span class="type">int</span> *, <span class="type">int</span>);</span><br></pre></td></tr></table></figure>

<p>其实 p 就是一个函数指针变量，可以指向一个函数带有两个参数的返回值为 int 类型的函数，我们使用 typedef 声明一下，将他变为一个类型：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="title function_">int</span> <span class="params">(*p)</span><span class="params">(<span class="type">int</span> *, <span class="type">int</span>)</span>;</span><br></pre></td></tr></table></figure>

<p>这样就相当于，我们定义了一个函数指针 p 的类型，它可以直接取代 int (xxx)(int *, int) 类型的函数指针，于是，上边的指针函数返回的函数指针就可以用新定义的类型 p 来定义了：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">p <span class="title function_">func</span><span class="params">(<span class="type">int</span>)</span>;</span><br></pre></td></tr></table></figure>

<p> p 就代表返回值的类型，就等价于 int (xxx)(int *, int) 。我是这样的理解的，也有可能理解的不到位，后边有什么问题的话会再修正。</p>
<h1 id="6-递归函数"><a href="#6-递归函数" class="headerlink" title="6.递归函数"></a><font size=3>6.递归函数</font></h1><p>一个函数在它的函数体内调用它自身称为<strong>递归调用</strong>，这种函数称为<strong>递归函数</strong>。</p>
<p>执行递归函数的时候这个函数将反复调用其自身，每调用一次就进入新的一层，当最内层的函数执行完毕后，再一层一层地由里到外退出。</p>
<p>递归函数调用的执行过程分为两个阶段。</p>
<ul>
<li>递推阶段：从原问题出发，按递归公式递推从未知到已知，最终达到递归终止条件。</li>
<li>回归阶段：按递归终止条件求出结果，逆向逐步代入递归公式，回归到原问题求解。</li>
</ul>
<h2 id="6-1常见的两个问题"><a href="#6-1常见的两个问题" class="headerlink" title="6.1常见的两个问题"></a><font size=3>6.1常见的两个问题</font></h2><h3 id="6-1-1阶乘问题"><a href="#6-1-1阶乘问题" class="headerlink" title="6.1.1阶乘问题"></a><font size=3>6.1.1阶乘问题</font></h3><p>在数学中，经常会看到阶乘：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220403150919614.png" alt="image-20220403150919614" style="zoom:50%;" />

<p>那么我们用 C 语言怎么实现呢？</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="title function_">factorial</span><span class="params">(<span class="type">int</span> n)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> a;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Input a number: &quot;</span>);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>, &amp;a);</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Factorial(%d) = %ld\n&quot;</span>, a, factorial(a));</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 求n的阶乘 */</span></span><br><span class="line"><span class="type">long</span> <span class="title function_">factorial</span><span class="params">(<span class="type">int</span> n)</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (n == <span class="number">0</span> || n == <span class="number">1</span>) </span><br><span class="line">	&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> </span><br><span class="line">	&#123;</span><br><span class="line">        <span class="keyword">return</span> factorial(n - <span class="number">1</span>) * n;  <span class="comment">/* 递归调用 */</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>然后在终端运行以下命令：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure>

<p>接着我们会在终端中看到以下输出信息（根据提示，手动输入一个数字）：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Input a number: 5</span><br><span class="line">Factorial(5) = 120</span><br></pre></td></tr></table></figure>

<p>接下来，我们可以分析一下， 5! 是怎么被求出来的。</p>
<details class="folding-tag" blue><summary> 点击查看分析过程 </summary>
              <div class='content'>
              <ul><li>递推阶段</li></ul><table>    <tr><td align="center">层数</td><td align="center">实参/形参</td><td align="center">调用形式</td><td align="center">需要计算的表达式</td><td align="center">需要等待的结果</td></tr>    <tr><td align="center">1</td><td align="center">n=5</td><td align="center">factorial(5)</td><td align="center">factorial(4) * 5</td><td align="center">factorial(4) 的结果</td></tr>    <tr><td align="center">2</td><td align="center">n=4</td><td align="center">factorial(4)</td><td align="center">factorial(3) * 4</td><td align="center">factorial(3) 的结果</td></tr>    <tr><td align="center">3</td><td align="center">n=3</td><td align="center">factorial(3)</td><td align="center">factorial(2) * 3</td><td align="center">factorial(2) 的结果</td></tr>    <tr><td align="center">4</td><td align="center">n=2</td><td align="center">factorial(2)</td><td align="center">factorial(1) * 2</td><td align="center">factorial(1) 的结果</td></tr>    <tr><td align="center">5</td><td align="center">n=1</td><td align="center">factorial(1)</td><td align="center">1</td><td align="center">无</td></tr>			    </table><ul><li>回归阶段</li></ul><table>    <tr><td align="center">层数</td><td align="center">调用形式</td><td align="center">需要计算的表达式</td><td align="center">内层函数的返回值</td><td align="center">表达式的值<br>（当次调用的结果）</td></tr>    <tr><td align="center">5</td><td align="center">factorial(1)</td><td align="center">1</td><td align="center">无</td><td align="center">1</td></tr>    <tr><td align="center">4</td><td align="center">factorial(2)</td><td align="center">factorial(1) * 2</td><td align="center">factorial(1) 的返回值，也就是 1</td><td align="center">2</td></tr>    <tr><td align="center">3</td><td align="center">factorial(3)</td><td align="center">factorial(2) * 3</td><td align="center">factorial(2) 的返回值，也就是 2</td><td align="center">6</td></tr>    <tr><td align="center">2</td><td align="center">factorial(4)</td><td align="center">factorial(3) * 4</td><td align="center">factorial(3) 的返回值，也就是 6</td><td align="center">24</td></tr>    <tr><td align="center">1</td><td align="center">factorial(5)</td><td align="center">factorial(4) * 5</td><td align="center">factorial(4) 的返回值，也就是 24</td><td align="center">120</td></tr></table>
              </div>
            </details>

<h3 id="6-1-2斐波那契数列"><a href="#6-1-2斐波那契数列" class="headerlink" title="6.1.2斐波那契数列"></a><font size=3>6.1.2斐波那契数列</font></h3><p>斐波那契数列是一个双层递归问题，它在一层中会调用自身两次。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/LV01-07-C%E8%AF%AD%E8%A8%80-%E5%87%BD%E6%95%B0/img/image-20220404065110961.png" alt="image-20220404065110961" style="zoom:50%;" />

<p>早研究这个数列的是斐波那契( Leonardo Fibonacci )，他当时是为了描述如下情况的兔子生长数目：</p>
<blockquote>
<ul>
<li>第一个月初有一对刚诞生的兔子</li>
<li>第二个月之后（第三个月初）它们可以生育</li>
<li>每月每对可生育的兔子会诞生下一对新兔子</li>
<li>兔子永不死去</li>
</ul>
<p>第一个月小兔子没有繁殖能力，所以还是一对。两个月后，生下一对小兔对数共有两对。三个月以后，老兔子又生下一对，因为小兔子还没有繁殖能力，所以一共是三对。</p>
<p>于是按照这样的规律，得到一串的数字：斐波那契数列： 1 ,  1 ,  2 ,  3 ,  5 ,  8 ,  13 ,  21 ,  34 ,  55 ,  89 ,  144 ,  233 ,  …… ，也就是说第一项和第二项是 1 ，之后的每一项为之前两项的和。</p>
</blockquote>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;time.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib</span><span class="params">(<span class="type">int</span> n)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> a;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Input a number: &quot;</span>);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>, &amp;a);</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;fib(%d) = %ld\n&quot;</span>, a, fib(a));</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 求斐波那契数列 */</span></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib</span><span class="params">(<span class="type">int</span> n)</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (n &lt; <span class="number">1</span> )  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span>(n == <span class="number">1</span> || n == <span class="number">2</span>)  <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> fib(n - <span class="number">1</span>) + fib(n - <span class="number">2</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>按照提示输入一个数字，  接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Input a number: 6</span><br><span class="line">fib(6) = 8</span><br></pre></td></tr></table></figure>
              </div>
            </details>

<h2 id="6-2递归的条件"><a href="#6-2递归的条件" class="headerlink" title="6.2递归的条件"></a><font size=3>6.2递归的条件</font></h2><p>每一个递归函数都应该只进行有限次的递归调用，如果无限制递归，那么最终将会使栈空间溢出。</p>
<p>要想让递归函数逐层进入再逐层退出，需要解决两个方面的问题：</p>
<ul>
<li><strong>存在限制条件，当符合这个条件时递归便不再继续</strong>。例如，上边的  factorial() ，当形参  n  等于  0  或  1  时，递归就结束。</li>
<li><strong>每次递归调用之后越来越接近这个限制条件</strong>。例如，上边的 factorial() ，每次递归调用的实参为  n - 1 ，这会使得形参  n  的值逐渐减小，越来越趋近于  1  或  0 。</li>
</ul>
<h2 id="6-3递归函数缺点"><a href="#6-3递归函数缺点" class="headerlink" title="6.3递归函数缺点"></a><font size=3>6.3递归函数缺点</font></h2><h3 id="6-3-1内存占用"><a href="#6-3-1内存占用" class="headerlink" title="6.3.1内存占用"></a><font size=3>6.3.1内存占用</font></h3><p>在程序占用的整个内存中，有一块内存区域叫做栈（ Stack ），它是专门用来给函数分配内存的，每次调用函数，都会将相关数据压入栈中，包括局部变量、局部数组、形参、寄存器、冗余数据等。</p>
<p>栈是针对线程来说的，每个线程都拥有一个栈。对每个线程来说，栈能使用的内存是有限的，一般是  1M~8M ，这在编译时就已经决定了，程序运行期间不能再改变。如果程序使用的栈内存超出最大值，就会发生栈溢出（ Stack Overflow ）错误。</p>
<details class="folding-tag" blue><summary> 点击查看常见编译器栈内存指定值 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">VC/VS 下，默认是 <span class="number">1</span>M</span><br><span class="line">C-Free 下，默认是 <span class="number">2</span>M</span><br><span class="line">Linux GCC 下，默认是 <span class="number">8</span>M</span><br></pre></td></tr></table></figure><p>【注意】这只是默认的栈内存大小，我们也可以通过参数来修改栈内存的大小。</p>
              </div>
            </details>

<p>发生函数调用时会将相关数据压入栈中，函数调用结束会释放这一部分内存。</p>
<p>对于递归函数，它的内部嵌套了对自身的调用，除非等到最内层的函数调用结束，否则外层的所有函数都不会调用结束。也就是说，外层函数暂停，一直处于等待状态，它要等待所有的内层函数调用完成后，它自己才能调用完成，完成后才能释放相应的内存。<strong>每一层的递归调用都会在栈上分配一块内存</strong>，有多少层递归调用就分配多少块相似的内存，所有内存加起来的总和是相当恐怖的，很容易超过栈内存的大小限制，这个时候就会导致程序崩溃。</p>
<h3 id="6-3-2时间成本"><a href="#6-3-2时间成本" class="headerlink" title="6.3.2时间成本"></a><font size=3>6.3.2时间成本</font></h3><p>每次调用函数都会在栈上分配内存，函数调用结束后再释放这一部分内存，内存的分配和释放都是需要时间的。</p>
<p>每次调用函数还会多次修改寄存器的值，函数调用结束后还需要找到上层函数的位置再继续执行，这也是需要时间的。</p>
<p>斐波那契数列计算的时候递归 n 次，时间复杂度 O(2^n) ，可以很好的展示时间成本。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;time.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib</span><span class="params">(<span class="type">int</span> n)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> a;</span><br><span class="line">	<span class="type">clock_t</span> time_start, time_end;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Input a number: &quot;</span>);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>, &amp;a);</span><br><span class="line">	time_start = clock();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;fib(%d) = %ld\n&quot;</span>, a, fib(a));</span><br><span class="line">	time_end = clock();</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;run time: %lfs\n&quot;</span>, (<span class="type">double</span>)(time_end - time_start)/ CLOCKS_PER_SEC );</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 求斐波那契数列 */</span></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib</span><span class="params">(<span class="type">int</span> n)</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (n &lt; <span class="number">1</span> )  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span>(n == <span class="number">1</span> || n == <span class="number">2</span>)  <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> fib(n - <span class="number">1</span>) + fib(n - <span class="number">2</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>按照提示输入一个数字，  接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Input a number: 50</span><br><span class="line">fib(50) = 12586269025</span><br><span class="line">run time: 42.039191s</span><br></pre></td></tr></table></figure><p> 42 秒的时间，这个时间成本有些过高了。</p>
              </div>
            </details>

<h3 id="6-4用迭代代替？"><a href="#6-4用迭代代替？" class="headerlink" title="6.4用迭代代替？"></a><font size=3>6.4用迭代代替？</font></h3><p>递归函数的内存成本和时间成本是函数实现原理层面的缺陷，无法优化。但是呢，很多能用递归解决的问题也能用迭代来解决。迭代，其实就是就是循环。与递归函数相比，迭代不但没有额外的内存成本，也没有额外的时间成本。</p>
<details class="folding-tag" blue><summary> 点击查看实例 </summary>
              <div class='content'>
              <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;time.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib_recursion</span><span class="params">(<span class="type">int</span> n)</span>;</span><br><span class="line"><span class="type">long</span> <span class="title function_">fib_iteration</span><span class="params">(<span class="type">int</span> n)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">int</span> a;</span><br><span class="line">	<span class="type">clock_t</span> time_start_recursion, time_end_recursion;</span><br><span class="line">    <span class="type">clock_t</span> time_start_iteration, time_end_iteration;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Please input a number: &quot;</span>);</span><br><span class="line">    <span class="built_in">scanf</span>(<span class="string">&quot;%d&quot;</span>, &amp;a);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* 递归的时间 */</span></span><br><span class="line">    time_start_recursion = clock();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Fib_recursion(%d) = %ld\n&quot;</span>, a, fib_recursion(a));</span><br><span class="line">    time_end_recursion = clock();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;run time with recursion: %lfs\n&quot;</span>, (<span class="type">double</span>)(time_end_recursion - time_start_recursion) / CLOCKS_PER_SEC );</span><br><span class="line">    <span class="comment">/* 迭代的时间 */</span></span><br><span class="line">    time_start_iteration = clock();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Fib_iteration(%d) = %ld\n&quot;</span>, a, fib_iteration(a));</span><br><span class="line">    time_end_iteration = clock();</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;run time with iteration: %lfs\n&quot;</span>, (<span class="type">double</span>)(time_end_iteration - time_start_iteration) / CLOCKS_PER_SEC);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 求斐波那契数列 --- 递归 */</span></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib_recursion</span><span class="params">(<span class="type">int</span> n)</span> </span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (n &lt; <span class="number">1</span> )  <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">	<span class="keyword">else</span> <span class="keyword">if</span>(n == <span class="number">1</span> || n == <span class="number">2</span>)  <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> fib_recursion(n - <span class="number">1</span>) + fib_recursion(n - <span class="number">2</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 求斐波那契数列 --- 迭代 */</span></span><br><span class="line"><span class="type">long</span> <span class="title function_">fib_iteration</span><span class="params">(<span class="type">int</span> n)</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="type">long</span> result;</span><br><span class="line">    <span class="type">long</span> previous_result;</span><br><span class="line">    <span class="type">long</span> next_older_result;</span><br><span class="line">    result = previous_result = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span> (n &gt; <span class="number">2</span>) </span><br><span class="line">	&#123;</span><br><span class="line">        n -= <span class="number">1</span>;</span><br><span class="line">        next_older_result = previous_result;</span><br><span class="line">        previous_result = result;</span><br><span class="line">        result = previous_result + next_older_result;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后在终端运行以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc test.c -Wall # 编译程序</span><br><span class="line">./a.out          # 执行可执行程序</span><br></pre></td></tr></table></figure><p>按照提示输入一个数字，  接着我们会在终端中看到以下输出信息：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Please input a number: 50</span><br><span class="line">Fib_recursion(50) = 12586269025</span><br><span class="line">run time with recursion: 45.457606s</span><br><span class="line">Fib_iteration(50) = 12586269025</span><br><span class="line">run time with iteration: 0.000005s</span><br></pre></td></tr></table></figure><p>这个时间差距是显而易见的。</p>
              </div>
            </details>


    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/203e48a8.html">LV01-07-C语言-函数</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2022年01月16日 - 14:25</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/203e48a8.html" title="LV01-07-C语言-函数">https://sumumm.github.io/post/203e48a8.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV01-C%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80/" rel="tag"><i class="fa fa-tag"></i> LV01-C语言基础</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/e57fdc7f.html" rel="prev" title="LV01-08-C语言-多文件">
                  <i class="fa fa-angle-left"></i> LV01-08-C语言-多文件
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/84847102.html" rel="next" title="LV01-06-C语言-指针">
                  LV01-06-C语言-指针 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">false</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
